package com.demo.test.leak

import android.app.Activity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.TextView
import com.fortest.R
import com.demo.component.LeakingSingleton1

/**
泄露方式：单例
泄露原因：LeakingSingleton1是个单例，其生命周期比Activity长。
在Activity中把一个view放到单例的List中，使得这个view会一直被单例长期持有，
因此即使Activity已经退出了，Activity仍然被单例所引用着，得不到释放。

泄露报告　－－　LeakCanary：
23643 bytes retained by leaking objects
Signature: b1a0c7dd3d1b3bffe8d213b4f69576aa2155859
┬───
│ GC Root: System class
│
├─ com.demo.component.LeakingSingleton1 class
│    Leaking: NO (a class is never leaking)
│    ↓ static LeakingSingleton1.leakedViews
│                               ~~~~~~~~~~~
├─ java.util.ArrayList instance
│    Leaking: UNKNOWN
│    ↓ ArrayList.elementData
│                ~~~~~~~~~~~
├─ java.lang.Object[] array
│    Leaking: UNKNOWN
│    ↓ Object[].[0]
│               ~~~
├─ android.widget.TextView instance
│    Leaking: YES (View.mContext references a destroyed activity)
│    mContext instance of com.demo.test.leak.ActivityLeakE_Instance_List with mDestroyed = true
│    View#mParent is set
│    View#mAttachInfo is null (view detached)
│    View.mID = R.id.helper_text
│    View.mWindowAttachCount = 1
│    ↓ TextView.mContext
╰→ com.demo.test.leak.ActivityLeakE_Instance_List instance
​     Leaking: YES (ObjectWatcher was watching this because com.demo.test.leak.ActivityLeakE_Instance_List received Activity#onDestroy() callback and Activity#mDestroyed is true)
​     key = af256a8b-8c1d-476e-96da-6ef3ddb6b410
​     watchDurationMillis = 7042
​     retainedDurationMillis = 2041
 **/
class ActivityLeakE_Instance_List : Activity() {
    val TAG = "ActivityLeakE_Instance"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_leak_common)
        val textView = findViewById<TextView>(R.id.helper_text)
        textView.text = "泄露方式：单例\n" +
                "泄露原因：LeakingSingleton1是个单例，其生命周期比Activity长。\n" +
                "在Activity中把一个view放到单例的List中，使得这个view会一直被单例长期持有，\n" +
                "因此即使Activity已经退出了，Activity仍然被单例所引用着，得不到释放。"

        val leakedView = findViewById<View>(R.id.helper_text)


        Log.d(TAG, "单例引用view，导致内存泄露")
        // Leak from Kotlin object singleton
        LeakingSingleton1.leakedViews.add(leakedView)

    }

}
